來試試看在 NX 中加入 Vue 框架的 Nuxt 專案。
首先目前 NX 還沒有針對支援 Nuxt 的擴充,所以大多步驟要手動進行。
要將 Nuxt 專案建立在 apps 底下,所以 cd 到 apps 後執行建立 Nuxt 的指令。
npx nuxi@latest init <app-name>
將生成一個帶著 package.json
的專案,這種結構其實也可以在 NX 底下運作,叫做 Package-based 結構,跟目前為止的 Integrated Repos 略有不同,這個之後再討論。
因為想要讓專案更密切的整合到目前的 Integrated Repos 結構,需要做一些對應的調整。
首先安裝需要的套件。
pnpm add -D @nx/devkit @nuxt/devtools nuxt
再來是更新 nuxt.config
,讓 Nuxt 可以參照到跟目錄的 tsconfig.base.json ,才能讀取到 lib 。
import { defineNuxtConfig } from 'nuxt/config';
import { join } from 'path';
import { workspaceRoot } from '@nx/devkit';
/**
* read the compilerOptions.paths option from a tsconfig and return as aliases for Nuxt
**/
function getMonorepoTsConfigPaths(tsConfigPath: string) {
const tsPaths = require(tsConfigPath)?.compilerOptions?.paths as Record<
string,
string[]
>;
const alias: Record<string, string> = {};
if (tsPaths) {
for (const p in tsPaths) {
// '@org/something/*': ['libs/something/src/*'] => '@org/something': '{pathToWorkspaceRoot}/libs/something/src'
alias[p.replace(/\/\*$/, '')] = join(
workspaceRoot,
tsPaths[p][0].replace(/\/\*$/, '')
);
}
}
return alias;
}
export default defineNuxtConfig({
/**
* aliases set here will be added to the auto generate tsconfig by Nuxt
* https://nuxt.com/docs/guide/directory-structure/tsconfig
**/
alias: getMonorepoTsConfigPaths('../../tsconfig.base.json'),
devtools: { enabled: true },
});
機著將 package.json
刪除後建立 project.json
取代,內容如下。
{
"name": "<app-name>",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "apps/<app-name>",
"projectType": "application",
"targets": {
"prepare": {
"executor": "nx:run-commands",
"options": {
"commands": ["nuxt prepare"],
"cwd": "{projectRoot}",
"forwardAllArgs": false
}
},
"build": {
"dependsOn": ["prepare"],
"executor": "nx:run-commands",
"options": {
"commands": ["nuxt build"],
"cwd": "{projectRoot}",
"forwardAllArgs": false
}
},
"serve": {
"dependsOn": ["prepare"],
"executor": "nx:run-commands",
"options": {
"commands": ["nuxt dev"],
"cwd": "{projectRoot}",
"forwardAllArgs": false
}
},
"generate": {
"dependsOn": ["prepare"],
"executor": "nx:run-commands",
"options": {
"commands": ["nuxt generate"],
"cwd": "{projectRoot}",
"forwardAllArgs": false
}
},
"preview": {
"dependsOn": ["prepare"],
"executor": "nx:run-commands",
"options": {
"commands": ["nuxt preview"],
"cwd": "{projectRoot}",
"forwardAllArgs": false
}
}
},
"tags": ["scope:<app-name>"],
"implicitDependencies": ["tag:scope:<app-name>"]
}
主要是在 targets 底下建立對應原本 package.json
的 scripts
的內容,因為沒有對應 Nuxt 的 NX 套件,只能全部用 run-commands
執行。
另外 Nuxt 在初始化的時候會執行 nuxt prepare
建立 .nuxt
目錄,所以這邊除 prepare
以外的指令都要依賴 。
如果每個指令都要執行一次 prepare
會很卡時間,所以記得到 nx.json
的 cacheableOperations
加上 ,好建立快取。
因為 NX 目前還無法識別 .vue 檔案,會無法自動偵測專案間的依賴,要利用 tag 的設定來手動建立關聯。
將來如果有引用到這個專案的 Vue lib ,就在該 lib 加上對應此專案的 tag ,以宣示關聯。
{
"tags": ["scope:<app-name>"]
}
最後在 .gitignore 忽略掉 Nuxt 動態產生的目錄
# Nuxt dev/build outputs
.output
.nuxt
.nitro
.cache
dist